# coding=utf-8

##############################################################################
#
# twitterpublisher.py
# A class to publish to twitter
#
# Copyright (c) 2011 Webcore Corp. All Rights Reserved.
#
##############################################################################
""" twitterpublisher.py - A class to publish to twitter

$Id: redditpublisher.py 20 2011-09-28 07:33:49Z shib.ats $
"""

__author__  = 'Atsushi Shibata <shibata@webcore.co.jp>'
__docformat__ = 'plaintext'
__licence__ = 'MIT'

import logging
from datetime import datetime
from utilities import urlopen, get_var_path
import re
import os.path
import shelve

from utilities import print_exc
from pluginbase import BasePublisher

import socket
#socketのタイムアウトを設定
socket.setdefaulttimeout(120)

COUNT = 50

BASE = """<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
<channel>
<title>%s</title>
%s
</channel>
</rss>"""

ITEM = """<item>
<title>
%s
</title>
<link>
%s
</link>
<guid isPermaLink="true">
%s
</guid>
<pubDate>%s</pubDate>
<description>
%s
</description>
</item>
"""

def get_point(uri):
    """
    A method to obtain point from uris of reddit entry.
    """
    r = urlopen(uri)
    body = r.read()
    r = re.findall("<span class='number'>(.+?)</span>", body)
    rn = 0
    try:
        rn = int(r[0])
    except:
        pass
    return rn


class RedditPublisher(BasePublisher):
    """
    Redditの投稿のうち，pointの高いフィードをRSSとしてpublishするクラス
    """
    def __init__(self, d):
        """
        Publisherの初期化method
        設定値を辞書で引数dに渡す
        設定値の辞書からは，以下のキーを読み込む
        
        threshold        : RSSに出力するポイントの下限(オプション,デフォルトは2)
        rsspath          : RSSとして書き出すファイルのパス(必須)
        """
        self.threshold = d.get('threshold', 2)
        self.rsspath = d.get('rsspath', '')

    def publish(self, settings, item):
        """
        publishを行うmethod
        """
        point = get_point(item['link'])
        go = False
        if point >= self.threshold:
            s = self.get_shelve()
            if str(item['link']) not in s:
                d = {'updated': item['updated'].strftime('%Y-%m-%dT%H:%M:%SZ'),
                     'title': item['title'],
                     'summary': '%s %s' % (self.id, str(point))}
                s[str(item['link'])] = d
            go = True
            s.sync()
        if go:
            # do something to write rss file to the path.
            logging.info("""read a feed item and stored it (%s/%s):\n%s""" %\
                                 (point, self.threshold, str(item['link'])))
        else:
            logging.info("""read a feed item and skipped it (%s/%s):\n%s""" %\
                                 (point, self.threshold, str(item['link'])))


    def finish_publish(self):
        """
        A hook method to finalize publish procedire
        """
        # deleting older items
        s = self.get_shelve()
        items = [(k, s[k]) for k in s.keys()]
        items.sort(lambda x, y : cmp(x[1]['updated'], y[1]['updated']))
        items.reverse()
        if len(items) > COUNT:
            items = items[:COUNT]
            # save the shelve in case of update
            s.clear()
            for i in items:
                s[i[0]] = i[1]
            s.sync()
        # writing rss file.
        f = open(self.rsspath, 'w')
        item_body = ""
        for i in items:
            try:
                d = i[1]
                i_s = ITEM % (d['title'], i[0], i[0], 
                             d['updated'], d['summary'])
                item_body += i_s
            except:
                pass
        f.write(BASE % (self.id, item_body))

    def test_publish(self, settings, item):
        point = get_point(item['link'])
        return point



    def get_shelve(self):
        """
        A method to obtain shelve object of the plugin.
        Pathes are descided by using instance id.
        """
        d = get_var_path()
        fp = os.path.join(d, self.id+'.dat')
        return shelve.open(fp, writeback=True)



